package com.pattern.behavioural.class02;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Ping
 * @date 2022/4/26 14:32
 **/
public class ObserverDemo {
    public static void main(String args[]) {
        Cat cat = new Cat() ;
        Dog dog = new Dog() ;
        Mouse mouse = new Mouse() ;
        /**
         * build relations
         */
        cat.addListener(dog);
        cat.addListener(mouse);
        /**
         * behaviours
         */
        cat.cry();
    }

}

/**
 * Subject content, the stuff which was intersted by Listeners .
 */
class CatCryEvent {
    private int vol ;
    private Date time ;

    public CatCryEvent(int vol) {
        this.vol = vol;
        this.time = new Date() ;
    }

    public int getVol() {
        return vol;
    }

    public String getTime() {
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(this.time);
    }
    public String toString() {
        return "vol: " + this.vol + " at: " + getTime() ;
    }
}

/**
 * Abstract Listener
 */
interface CatCryListener {
    /**
     *  update method for listeners.
     * @param cryEvent
     */
    public void reactionOn(CatCryEvent cryEvent) ;
}

/**
 * Subject
 */
class Cat {
    /**
     * containing all related listeners by list, or other collections.
     */
    private List<CatCryListener> listeners ;

    public Cat() {
        this.listeners = new ArrayList<>() ;
    }

    public void addListener(CatCryListener listener) {
        this.listeners.add(listener) ;
    }

    /**
     * the method to generate the cry event,and it would
     * invoke all related updating methods.
     */
    public void cry() {
        /*
        step1. generate a cry event
         */
        CatCryEvent event = new CatCryEvent(60) ;
        /**
         * step2. notifying all listeners to update their states
         */
        this.listeners.stream().forEach(lis -> lis.reactionOn(event)) ;
    }

}

/**
 * Concrete Listener
 */
class Mouse implements CatCryListener {
    @Override
    public void reactionOn(CatCryEvent cryEvent) {
        System.out.println("A Mouse fleeted away on cat cry event: " + cryEvent) ;
    }
}

/**
 * Concrete Listener.
 */
class Dog implements CatCryListener {

    @Override
    public void reactionOn(CatCryEvent cryEvent) {
        System.out.println("A Dog keep sleeping on cat cry event: " + cryEvent) ;
    }
}


